package com.x.utils.http;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.Charsets;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

/**
 * 网络请求访问工具
 * 
 * @author Kenmy
 * 
 */
public class DBUrlUtil {

	private static Logger log = Logger.getLogger(DBUrlUtil.class);

	/**
	 * 网络请求 GET
	 * 
	 * @param uri
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @return int 返回状态吗
	 */
	public static int GetCode(String uri) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
		int code = 0;
		try {
			HttpGet httpGet = new HttpGet(uri);
			log.info("GET >>> " + httpGet.getURI());
			httpGet.setConfig(requestConfig);
			response = httpclient.execute(httpGet);
			code = response.getStatusLine().getStatusCode();
		} catch (Exception e) {
			log.error(e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				httpclient.close();
			} catch (IOException e) {
				log.error(e);
			}
		}
		return code;
	}

	/**
	 * 网络请求 GET
	 * 
	 * @param uri
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @return string
	 */
	public static String Get(String uri, String params) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		StringBuffer sb = new StringBuffer("");
		CloseableHttpResponse response = null;
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
		try {
			String p = (params == null) ? "" : "?" + params;
			HttpGet httpGet = new HttpGet(uri + p);
			log.info("GET >>> " + httpGet.getURI());
			httpGet.setConfig(requestConfig);
			response = httpclient.execute(httpGet);
			int code = response.getStatusLine().getStatusCode();
			if (code == 200) {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					sb.append(EntityUtils.toString(entity, "UTF-8"));
				}
			} else {
				sb.append(code);
			}
		} catch (Exception e) {
			log.error(e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				if (httpclient != null) {
					httpclient.close();
				}
			} catch (IOException e) {
				log.error(e);
			} finally {
				response = null;
				httpclient = null;
			}
		}
		log.info("GET BACK >>> " + sb.toString());
		return sb.toString();
	}

	/**
	 * 网络请求 GET
	 * 
	 * @param uri
	 *            请求地址
	 * @return string
	 */
	public static String Get(String uri) {
		return Get(uri, null);
	}

	/**
	 * 网络请求 POST
	 * 
	 * @param uri
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @return string
	 */
	public static String Post(String uri, String params) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		StringBuffer sb = new StringBuffer("");
		CloseableHttpResponse response = null;
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
		try {
			StringEntity strEntity = new StringEntity(params, ContentType.create("application/x-www-form-urlencoded", Consts.UTF_8));
			strEntity.setContentEncoding("UTF-8");
			HttpPost httppost = new HttpPost(uri);
			httppost.setEntity(strEntity);
			httppost.setConfig(requestConfig);
			log.info("POST >>> " + httppost.getURI());
			log.info("POST DATA >>>" + EntityUtils.toString(strEntity));
			response = httpclient.execute(httppost);
			int code = response.getStatusLine().getStatusCode();
			if (code == 200) {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					sb.append(EntityUtils.toString(entity, "UTF-8"));
				}
			} else {
				sb.append(code);
			}
		} catch (Exception e) {
			log.error(e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				if (httpclient != null) {
					httpclient.close();
				}
			} catch (IOException e) {
				log.error(e);
			} finally {
				response = null;
				httpclient = null;
			}
		}
		log.info("POST BACK >>> " + sb.toString());
		return sb.toString();
	}

	/**
	 * 网络请求 POST
	 * 
	 * @param uri
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @return string
	 */
	public static int PostForCode(String uri, String params) {
		int code = -1;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000).build();
		try {
			StringEntity strEntity = new StringEntity(params, ContentType.create("application/x-www-form-urlencoded", Consts.UTF_8));
			strEntity.setContentEncoding("UTF-8");
			HttpPost httppost = new HttpPost(uri);
			httppost.setEntity(strEntity);
			httppost.setConfig(requestConfig);
			log.info("POST >>> " + httppost.getURI());
			log.info("POST DATA >>>" + EntityUtils.toString(strEntity));
			response = httpclient.execute(httppost);
			code = response.getStatusLine().getStatusCode();
		} catch (Exception e) {
			log.error(e);
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				if (httpclient != null) {
					httpclient.close();
				}
			} catch (IOException e) {
				log.error(e);
			} finally {
				response = null;
				httpclient = null;
			}
		}
		return code;
	}

	/**
	 * 该方法主要是给前台传送一个字符串，多用于ajax请求
	 * 
	 * @param message
	 */
	public static void SendResult(HttpServletResponse response, Object message) {
		PrintWriter io = null;
		try {
			io = response.getWriter();
			io.print(message);
			io.flush();
		} catch (Exception e) {
			log.error("response io异常", e);
		} finally {
			if (io != null) {
				io.close();
			}
		}
	}

	/**
	 * 该方法主要用于前端下载Csv格式文件
	 * 
	 * @param fileName
	 * @param response
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void exploreCsv(String fileName, HttpServletResponse response) throws FileNotFoundException, IOException {
		File file = new File("export_csv" + File.separator + fileName);

		response.setContentType("application/csv;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=" + new String((fileName).getBytes(Charsets.UTF_8), Charsets.ISO_8859_1));

		if (file.exists()) { // 如果文件存在
			InputStream in = null;
			try {
				in = new FileInputStream(file);
				response.setCharacterEncoding("UTF-8");
				OutputStream out = response.getOutputStream();
				int b;
				while ((b = in.read()) != -1) {
					out.write(b);
				}
				out.close();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
				}
			}
		}
	}

	/**
	 * 判断是否为ajax请求
	 * 
	 * @param request
	 * @return
	 */
	public static boolean isAjax(HttpServletRequest request) {
		if (request != null && "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With")))
			return true;
		return false;
	}

	/**
	 * 获取cookies值
	 * 
	 * @param request
	 * @param cookieName
	 * @return
	 */
	public static String getCookieValue(HttpServletRequest request, String cookieName) {
		Cookie[] cookies = request.getCookies();
		if (cookies != null && cookies.length > 0) {
			for (Cookie cookie : cookies) {
				if (cookie.getName().equals(cookieName)) {
					return cookie.getValue();
				}
			}
		}
		return null;
	}

	/**
	 * 设置cookies
	 * 
	 * @param response
	 * @param cookieName
	 * @param value
	 * @param cookieAge
	 */
	public static void setCookieValue(HttpServletResponse response, String cookieName, String value, int cookieAge) {
		Cookie cookie = new Cookie(cookieName, value);
		cookie.setPath("/");
		cookie.setMaxAge(cookieAge);
		response.addCookie(cookie);
	}

	/**
	 * 清除cookies
	 * 
	 * @param request
	 * @param response
	 */
	public static void clearCookie(HttpServletRequest request, HttpServletResponse response) {
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			// for (int i = 0, len = cookies.length; i < len; i++) {
			Cookie cookie = new Cookie("JSESSIONID", null);
			cookie.setMaxAge(0);
			cookie.setPath("/test_manage");
			response.addCookie(cookie);

			cookie = new Cookie("JSESSIONID", null);
			cookie.setMaxAge(0);
			cookie.setPath("/test_manage/");
			response.addCookie(cookie);
			// }
		}
	}

	/**
	 * 
	 * @param url
	 * @param params
	 * @return
	 */
	public static String postHttps(String url, String params) {
		InputStream urlStream = null;
		BufferedReader reader = null;
		try {
			log.info("HTTPS POST >>> " + url);
			log.info("HTTPS POST DATA >>>" + params);
			verifierHostname();
			URLConnection urlCon = (new URL(url)).openConnection();
			urlCon.setDoOutput(true);
			OutputStreamWriter out = new OutputStreamWriter(urlCon.getOutputStream(), "utf-8");
			out.write(params);
			// remember to clean up
			out.flush();
			out.close();
			// 一旦发送成功，用以下方法就可以得到服务器的回应：
			StringBuilder sTotalString = new StringBuilder();
			String sCurrentLine = "";
			urlStream = urlCon.getInputStream();
			reader = new BufferedReader(new InputStreamReader(urlStream));
			while ((sCurrentLine = reader.readLine()) != null) {
				sTotalString.append(sCurrentLine);
			}
			log.info("HTTPS RETURN >>>" + sTotalString.toString());
			return sTotalString.toString();
		} catch (Exception e) {
			System.out.println(e);
			log.error("{}", e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					log.error("{}", e);
				}
			}
			if (urlStream != null) {
				try {
					urlStream.close();
				} catch (IOException e) {
					log.error("{}", e);
				}
			}
		}
		return "";
	}

	private static void verifierHostname() throws NoSuchAlgorithmException, KeyManagementException {
		SSLContext sslContext = null;
		sslContext = SSLContext.getInstance("TLS");
		X509TrustManager xtm = new X509TrustManager() {
			public void checkClientTrusted(X509Certificate[] chain, String authType) {
			}

			public void checkServerTrusted(X509Certificate[] chain, String authType) {
			}

			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		X509TrustManager[] xtmArray = new X509TrustManager[] { xtm };
		sslContext.init(null, xtmArray, new java.security.SecureRandom());
		if (sslContext != null) {
			HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
		}
		HostnameVerifier hnv = new HostnameVerifier() {
			public boolean verify(String hostname, SSLSession session) {
				return true;
			}
		};
		HttpsURLConnection.setDefaultHostnameVerifier(hnv);
	}
	
	public static void main(String[] args) {
		System.out.println(postHttps("https://yuangu.vipqn.com:7080/yuangu_manage/auth/login", null));
	}

}
